package demo.terrain;

import org.lwjgl.input.Mouse;

import engine.camera.Camera;
import engine.gameObject.GameObject;

public class TerrainCamera extends Camera {

	public static final float INITIAL_ANGLE_SPEED = (float)Math.toRadians(0.2);

	private float angleUp; 
	
	private float angleSpeed;
	
	private float angleFloor;
	
	private GameObject player;
	
	public TerrainCamera(GameObject player) {
		this.player = player;
		
		angleSpeed = INITIAL_ANGLE_SPEED;
		
		setNear(0.1f);
		setNearPane(40);
		setFarPane(100);
		setOpenAngle(45);
	}
	
	@Override
	public void update(float timeElapsed) {		
		updateLookPosition();
	}
	
	/**
	 * This updates the lookAt position after changing the eye position of the camera. 
	 */
	private void updateLookPosition() {
		setEyeX(player.getPosX());
		setEyeY(player.getPosY());
		setEyeZ(player.getPosZ());
		
		float h = (float)Math.cos(angleUp);
		setLookAtX(getEyeX() + (float)Math.sin(angleFloor) * h);
		setLookAtY(getEyeY() + (float)Math.sin(angleUp));
		setLookAtZ(getEyeZ() + (float)Math.cos(angleFloor) * h);
	}
	
	@Override
	public void setWidth(int width) {
		super.setWidth(width);
		
		Mouse.setCursorPosition(getWidth() / 2, getHeight() / 2);
	}
	
	@Override
	public void setHeight(int height) {
		super.setHeight(height);
		
		Mouse.setCursorPosition(getWidth() / 2, getHeight() / 2);
	}
	
	public void mouseMoved(int x, int y, int button) {
		angleUp = (float)Math.max(-Math.toRadians(89), Math.min(Math.toRadians(89), angleUp + (y - (getHeight() / 2)) * angleSpeed));
		angleFloor += ((getWidth() / 2) - x) * angleSpeed;
		
		Mouse.setCursorPosition(getWidth() / 2, getHeight() / 2);
	}
	
	public float getAngleFloor() {
		return angleFloor;
	}
}
